Last Mile Fleet Solution (LMFS)

Descripcion

Explicación de los componentes e implementación del entorno LMFS de Google

Documentación LMFS

Código ejemplo

Componentes

Fleet Engine

Driver SDK

Navigation SDK

JavaScript Journey Sharing library

Routes Preferred APIs

Metodo Backend

Modificamos el archivo backend/src/main/resources/config.properties para incluir las cuentas de correo necesarias y el API KEY

El provider-id podemos consultarlo aqui:

Y las distintas cuentas para cada uno de los servicios las creamos aqui:

Cada una de las cuentas tiene que tener los siguientes permisos:

Una vez tenemos el archivo con todas las configuraciones ejecutamos lo siguiente comandos:

cd backend gradlew wrapper gradlew test gradlew appengineRun
Troubleshooting Backend

Cannot retrieve credentials for default application.

Este error se debe porque no estamos autenticados con gcloud, para autenticarnos usamos los siguientes comandos:

gcloud auth login gcloud auth application-default login gcloud config set project PROJECT_ID

warnAboutProblematicCredentials

Este error se da porque, a pesar de estar autenticados, no tenemos todos los permisos necesarios con nuestra cuenta en el proyecto.

La cuenta que estemos usando tiene que tener el permiso de "Service Account Token Creator"

En la sección IAM de nuestro proyecto podemos consultar los roles asignados a cada cuenta.

Unable to create a DevAppServer

Este error se produce al utilizar una versión incorrecta del jdk:

Para ejecutar este proyecto es necesaria la versión 11 del JDK, tenemos que tener definida la variable de entorno JAVA_HOME con la carpeta del jdk 11

gcloud crashed (FileNotFoundError)

Al lanzar la applicación de backend obtenemos el siguiente mensaje:

Si accedemos a la ruta que aparece en el error vemos que ese archivo si que existe, pero el sistema no puede acceder a él.

Este error se da porque la ruta es demasiado larga, windows por defecto tiene un limite de 256 caracteres para las rutas, para solucionar este error tenemos que modificar la siguiente clave del registro:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled

Modificamos el valor de 0 a 1. Una vez modificada la clave reiniciamos el sistema y el error ya no debería de aparecer.

Metodo Android App

Primero tenemos que modificar los siguientes archivos para indicar la API KEY y el path del ANDROID SDK:

Consultas con curl

Google fleet engine

JWT Authorization

Usamos el siguiente comando para crear una nuevo vehiculo en el fleet engine,

curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles?deliveryVehicleId=${VEHICLE_ID}" \
  -H "Content-type: application/json" \
  -H "Authorization: Bearer ${JWT}" \
--data-binary @- << EOM
{
  "attributes": [{"key": "model", "value": "sedan"}],
  "lastLocation": {"location": {"latitude": 12.1, "longitude": 14.5}}
}
EOM 

Tenemos que modificar ${PROJECT_ID} por el nombre de nuestro proyecto, ${VEHICLE_ID} por el id que le queramos dar al nuevo vehiculo, y ${JWT} por nuestro token JWT (A continuación se muestra como generar el token JWT).

Generar token JWT

Primero necesitamos crear una cuenta de servicio en nuestro proyecto de google cloud que tenga los roles: "Fleet Engine Delivery Super User" y "Service Account Token Creator"

A continuación en la cuenta de servicio que acabamos de crear tenemos que generar una nueva clave:

Cuentas de servicio > (seleccionamos nuestra cuenta) > Claves > Agregar Clave > Crear clave nueva

Una vez creada la nueva clave se descargará un archivo JSON, con toda la información necesaria que necesitamos para generar el JWT

Para generar el token JWT lo haremos con un script de Python.

Primero necesitamos instalar dos modulos de python:

pip install PyJWT pip install cryptography

El script es el siguiente:

 import jwt
import time

iat = time.time()
exp = iat + 3600
payload = {'iss': 'CUENTA_DE_SERVICIO',
            'sub': 'CUENTA_DE_SERVICIO',
            'aud': 'https://fleetengine.googleapis.com/',
            'iat': iat,
            'exp': exp,
            'authorization': {
                'deliveryvehicleid': '*'
            } }
additional_headers = {'kid': 'PRIVATE_KEY_ID'}
signed_jwt = jwt.encode(payload, 'PRIVATE_KEY', headers=additional_headers,
                        algorithm='RS256')
print(signed_jwt)

Tenemos que modificar los valores CUENTA_DE_SERVICIO, PRIVATE_KEY_ID y PRIVATE_KEY, para substituirlos por los valores que aparecen en el JSON que hemos descargado al generar la clave de nuestra cuenta de servicio.

El campo de authorization tendremos que modificarlo según la consulta que vayamos a realizar, en este caso usamos deliveryvehicleid porque vamos a crear un vehiculo, otras opciones del campo authorization son:

Una vez tengamos todo modificado ejecutamos el script y nos devolverá un token como el siguiente:

Este token es lo que tenemos que substituit en el comando curl por ${JWT}

Al ejecutar el comando de manera satisfactoria obtenemos una respuesta como esta:

Consultar vehiculo creado

Para realizar una consulta del recurso que acabamos de crear lo hacemos con el siguiente comando:

curl -H "Authorization: Bearer ${JWT}" \
  "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}"

Nuevamente tenemos que realizar los cambios de los valores ${JWT}, ${PROJECT_ID} y ${VEHICLE_ID}

La respuesta será algo como esto:

Troubleshooting

Al hacer la solicitud con curl nos podemos encontrar con los siguientes errores:

Error 1:

"code": 403,
"message": "JWT does not contain any scopes.",
"status": "PERMISSION_DENIED"

Este error se da porque no hemos indicado el campo authorization a la hora de generar el token JWT

Error 2:

"code": 403,
"message": "User does not have permissions to complete this request",
"status": "PERMISSION_DENIED"

Este error se da porque la cuenta de servicio que estamos utilizando no tiene los roles necesarios para llevar acabo la operación, la cuenta debería de tener los roles: "Fleet Engine Delivery Super User" y "Service Account Token Creator"

Error 3:

"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.
See https://developers.google.com/identity/sign-in/web/devconsole-project.",
  "status": "UNAUTHENTICATED"

Este error se da cuando alguno de los datos que hemos indicado al generar el token es incorrecto, algun nombre de cuenta mal puesto, algun id mal puesto o alguna url mal puesta...

Error 4:

"code": 403,
"message": "JWT does not contain a matching scope for requested delivery vehicle.",
"status": "PERMISSION_DENIED"

Este error se da cuando en el campo authorization estamos indicando un parámetro que no es correcto para la solicitud que estámos realizando, por ejemplo usar taskid en vez de deliveryvehicleid

Tags

java | LMFS